﻿using System;
using System.Globalization;
using System.Configuration;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Data.Linq.SqlClient;
using System.Text;
using System.Web;
using System.IO;
using System.Net.Mail;
using IntraVision.Web;
using IntraVision.Web.Filter;
using IntraVision.Web.Security;
using Model;
using LZMA;
using EmitMapper;
using EmitMapper.MappingConfiguration;

using NotarialService.Classes;

public enum OrderDocTemplateType : int
{
    NotarialDocTemplate = 1,
    UserDocTemplate = 2
}

public class OrderDocTemplateInfo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string CreateDateStr { get; set; }
    public int OrderId { get; set; }
}

public class Notarius
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class NotariusList
{
    public IList<Notarius> Items { get; set; }
    public bool IOisActive { get; set; }
}

public partial class OrderController : TableController<NotarialServiceDataContext, Order>
{
    #region список документов в соответствии с типом нотариальных действий
    public void GetDocTemplateList()
    {
        var notarialActionId = Convert.ToInt32(Request["notarialactionid"]);
        var orderId = Convert.ToInt32(Request["orderid"]);
        if (notarialActionId < 1) return;

        LayoutPath = "none";
        TemplatePath = "~/views/order/_doctemplates.haml";

        PrepareDocTemplateList(notarialActionId, orderId);

        RenderView();
    }

    public void PrepareDocTemplateList(int notarialActionId, int orderId)
    {
        if (notarialActionId < 1) return;
        using (var dc = new NotarialServiceDataContext())
        {
            var entity = dc.NotarialActions.Single(na => na.Id == notarialActionId);
            var list = entity.NotarialActionFiles
                            .Where(f => !f.IsDeleted)
                            .Select(f => new OrderDocTemplateInfo
                            {
                                Id = f.Id,
                                Name = f.Name,
                                CreateDateStr = f.Created.ToString("dd.MM.yyyy"),
                                OrderId = orderId
                            }).ToList();

            ViewData["doctemplatesorderid"] = orderId;
            ViewData["doctemplates"] = list;
        }
    }
    #endregion

    #region Upload-файлы заявки
    private void UploadFiles(Order order, User user)
    {
        if (Request.Files.Count > 0)
        {
            for (int i = 0; i < Request.Files.Count; i++)
            {
                if (Request.Files.AllKeys[i].Trim().StartsWith("userversion"))
                    continue;

                var file = Request.Files[i];
                var fileContent = RequestHelper.GetPostedFileContent(file);
                if (fileContent.Length == 0) continue;

                var tf = new OrderFile();
                tf.Data = fileContent;
                tf.Created = DateTime.Now;
                tf.CreatorId = user.Id;
                tf.Name = System.IO.Path.GetFileName(file.FileName);
                tf.IsFinal = (Request.Files.AllKeys[i] == "resultfile");
                order.OrderFiles.Add(tf);
            }
        }
    }

    public void RemoveFile(string fileid)
    {
        var user = Session["user"] as User;
        using (var dc = new NotarialServiceDataContext())
        {
            int fid;
            Int32.TryParse(fileid, out fid);

            var file = dc.OrderFiles.Single(f => f.Id == fid);

            try
            {
                var order = file.Order;
                file.IsDeleted = true;
                file.DeletedDate = DateTime.Now;
                dc.SubmitChanges();
            }
            catch (Exception ex)
            {
                RenderJSON(new AJAXResult(ex));
                return;
            }
            RenderJSON(new AJAXResult { Id = fileid });
        }
    }

    public void ViewFile(string fileid)
    {
        using (var dc = new NotarialServiceDataContext())
        {
            int fid = 0;
            Int32.TryParse(fileid, out fid);

            var file = dc.OrderFiles.Single(f => f.Id == fid);

            Response.ContentType = "application/octet-stream";
            Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + file.Name + "\"");
            Response.HeaderEncoding = Encoding.GetEncoding("windows-1251");
            Response.ContentEncoding = Encoding.GetEncoding("windows-1251");
            byte[] bytes;
            try
            {
                bytes = Extractor.ExtractBytes(file.Data.ToArray());
            }
            catch
            {
                bytes = file.Data.ToArray();
            }
            Response.BinaryWrite(bytes);

            Response.Flush();
            Response.End();
        }
    }
    #endregion

    #region Шаблонные докуменьты WebDAV         
    //создание веб-дав файла по файлу нотариального действия
    public void EditDocTemplateBegin(string fileId, string orderId, string notariusId)
    {
        using (var dc = new NotarialServiceDataContext())
        {
            int fid = 0;
            Int32.TryParse(fileId, out fid);
            int oid = 0;
            Int32.TryParse(orderId, out oid);
            int nid = 0;
            Int32.TryParse(notariusId, out nid);
            if (fid < 1 || oid < 1 || nid < 1)
            {
                RenderJSON(new AJAXResult(new ArgumentException()));
                return;
            }

            var file = dc.NotarialActionFiles.Single(f => f.Id == fid);
            var fileName = GenerateOrderDocTemplateName(oid, file.NotarialAction.Name, file.Name, (Session["User"] as User), 1, nid);
            byte[] bytes;
            try
            {
                bytes = Extractor.ExtractBytes(file.Data.ToArray());
            }
            catch
            {
                bytes = file.Data.ToArray();
            }

            try
            {                
                var id = CreateOrderDocTemplateFile(oid, fileName, null, (Session["user"] as User).Id, file.Data, OrderDocTemplateType.NotarialDocTemplate);
                var folderPath = GetFolderPath(ConfigurationManager.AppSettings["WebDAVaddress"], id, oid);
                File.WriteAllBytes(Path.Combine(folderPath, fileName), bytes);
                RenderJSON(new AJAXResult { Id = id.ToString(), Description = Path.Combine(folderPath.Replace(ConfigurationManager.AppSettings["WebDAVaddress"], ""),fileName) });
            }
            catch (Exception ex)
            {
                RenderJSON(new AJAXResult(ex));
                return;
            }
        }
    }

    //создание веб-дав файла по существующему файлу 
    public void EditDocTemplate(string fileId, string orderId, string notariusId)
    {
        using (var dc = new NotarialServiceDataContext())
        {
            int fid = 0;
            Int32.TryParse(fileId, out fid);
            int oid = 0;
            Int32.TryParse(orderId, out oid);
            int nid = 0;
            Int32.TryParse(notariusId, out nid);

            var file = dc.OrderDocTemplates.Single(f => f.Id == fid);
            //int? version = file.Version + 1;
            byte[] bytes;
            try
            {
                bytes = Extractor.ExtractBytes(file.Data.ToArray());
            }
            catch
            {
                bytes = file.Data.ToArray();
            }
            var fileName = ChangeVersion(file.Name); //temp

            try
            {
                var id = CreateOrderDocTemplateFile(oid, fileName, (int?)file.Id, (Session["user"] as User).Id, file.Data, (OrderDocTemplateType)file.TemplateTypeId);
                var folderPath = GetFolderPath(ConfigurationManager.AppSettings["WebDAVaddress"], id, oid);
                File.WriteAllBytes(Path.Combine(folderPath, fileName), bytes);
                RenderJSON(new AJAXResult { Id = id.ToString(), Description = Path.Combine(folderPath.Replace(ConfigurationManager.AppSettings["WebDAVaddress"], ""),fileName)});
            }
            catch (Exception ex)
            {
                RenderJSON(new AJAXResult(ex));
                return;
            }
        }
    }

    private static string ChangeVersion(string fileName)
    {
        var finish = fileName.LastIndexOf('.');
        var start = fileName.LastIndexOf("_v");

        if (start < 0 || finish < 0)
            return fileName;

        start += 2;

        var cut = fileName.Substring(start, finish - start);
        int version = 0;
        if (Int32.TryParse(cut, out version) && version > 0)
        {
            ++version;
            return fileName.Replace("_v" + cut, "_v" + version);
        }
        return fileName;
    }

    //просмотр версионного файла 
    public void ViewVersionFile(string fileid)
    {
        using (var dc = new NotarialServiceDataContext())
        {
            int fid = 0;
            Int32.TryParse(fileid, out fid);
            var file = GetVersionFileNameById(fid);

            Response.ContentType = "application/octet-stream";
            Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + file.Name + "\"");
            Response.HeaderEncoding = Encoding.GetEncoding("windows-1251");
            Response.ContentEncoding = Encoding.GetEncoding("windows-1251");

            // byte[] bytes = File.ReadAllBytes(Path.Combine(folderPath, fileName));

            byte[] bytes;
            try
            {
                bytes = Extractor.ExtractBytes(file.Data.ToArray());
            }
            catch
            {
                bytes = file.Data.ToArray();
            }
            Response.BinaryWrite(bytes);

            Response.Flush();
            Response.End();
        }
    }
    #endregion

    #region НЕшаблонные докуменьты WebDAV
    private void UploadUserVersionFiles(Order order, User user)
    {
        if (Request.Files.Count > 0)
        {
            for (int i = 0; i < Request.Files.Count; i++)
            {
                if (!Request.Files.AllKeys[i].Trim().StartsWith("userversion"))
                    continue;

                var file = Request.Files[i];
                var fileContent = RequestHelper.GetPostedFileContent(file);
                if (fileContent.Length == 0) continue;

                var tf = new OrderDocTemplate                
                { 
                    Name = SetVersion(System.IO.Path.GetFileName(file.FileName)), 
                    CreateDate = DateTime.Now,  
                    ParentId = null,
                    OrderId = order.Id,
                    Data = fileContent,
                    CreatorId = user.Id,
                    TemplateTypeId = (int)OrderDocTemplateType.UserDocTemplate,
                    IsNotTemp = true
                };
                order.OrderDocTemplates.Add(tf);
            }
        }
    }

    private static string SetVersion(string getFileName)
    {
        var index = getFileName.LastIndexOf('.');
        if (index > 1)
            return getFileName.Insert(index, "_v1");
        return getFileName;
    }

    #endregion

    private static int CreateOrderDocTemplateFile(int orderId, string name, int? parentId, int userId, System.Data.Linq.Binary sourceFile, OrderDocTemplateType type)
    {
        using (var dc = new NotarialServiceDataContext())
        {
            var doc = new OrderDocTemplate 
            { 
                Name = name, 
                CreateDate = DateTime.Now,  
                ParentId = parentId,
                OrderId = orderId,
                Data = sourceFile,
                CreatorId = userId,
                TemplateTypeId = (int)type
            };
            dc.OrderDocTemplates.InsertOnSubmit(doc);
            dc.SubmitChanges();
            return doc.Id;
        }
    }

    private void CheckNewDocTemplates(Order entity)
    {
        var ids = RequestHelper.GetIdsFromString(Request["newdoctemplates"]);
        if (ids.Count() == 0) return;
        using (var dc = new NotarialServiceDataContext())
        {
            var docs = (from dt in dc.OrderDocTemplates where ids.Contains(dt.Id) select dt);
            var rootfolderPath = ConfigurationManager.AppSettings["WebDAVaddress"];
            foreach (var file in docs)
            {
                var folderPath = GetFolderPath(rootfolderPath, file.Id, entity.Id);
                var filePath = Path.Combine(folderPath, file.Name);
                if (File.Exists(filePath))
                {
                    var fileInfo = new FileInfo(filePath);
                    if (fileInfo.LastWriteTime > file.CreateDate.AddSeconds(1))
                    {
                        var data = File.ReadAllBytes(filePath);
                        //Сжатие файла
                        try
                        {
                            file.Data = new System.Data.Linq.Binary(Compressor.CompressBytes(data));
                        }
                        catch
                        {
                            file.Data = new System.Data.Linq.Binary(data);
                        }
                        file.OrderId = entity.Id;
                        file.IsNotTemp = true;
                    }
                    else
                    {
                        dc.OrderDocTemplates.DeleteOnSubmit(file);
                    }
                    File.Delete(filePath);
                }
            }
            dc.SubmitChanges();
        }
    }

    private static string GetDocumentName()
    {
        return null;
    }

    private static OrderDocTemplate GetVersionFileNameById(int fileId)
    {
        using (var dc = new NotarialServiceDataContext())
        {
            var file = dc.OrderDocTemplates.Single(d => d.Id == fileId);
            return file;
        }
    }

    private static string GenerateOrderDocTemplateName(int orderId, string notarialActionName, string fileName, User user, int version, int nid)
    {
        //{actionName}_{clients}_{userName}_.{extension}
        var sb = new StringBuilder();
        //имя шаблона
        sb.Append(notarialActionName);
        //sb.Append(GetFileNameWithoutExtension(fileName));
        sb.Append("_");
        sb.Append(orderId);
        sb.Append("_");
        //клиенты
        //foreach (var client in order.OrderClients)
        //sb.AppendFormat("{0}_", client.Name);
        //нотариус
        sb.Append(user.FIO);
        sb.Append("_");
        //sb.Append(Math.Abs((double)DateTime.Now.ToString().GetHashCode()));

        sb.Append(GetCurrentDirectorName(nid));
        sb.Append("_v");
        sb.Append(version);
        sb.Append(GetFileExtension(fileName));

        return sb.ToString();
    }

    private static string GetCurrentDirectorName(int an)
    {
        string result;
        using (var dc = new NotarialServiceDataContext())
        {
            var setting = dc.NotarialSettings.FirstOrDefault();
            result = (an != 1)
                       ? string.Format("{0} {1}.{2}.",
                                       setting.LastNameIO,
                                       setting.NameIO.Trim().Length > 0
                                           ? setting.NameIO.Trim().ToUpper()[0].ToString()
                                           : "",
                                       setting.PatronymicNameIO.Trim().Length > 0
                                           ? setting.PatronymicNameIO.Trim().ToUpper()[0].ToString()
                                           : "")

                       : string.Format("{0} {1}.{2}.",
                                       setting.LastName,
                                       setting.Name.Trim().Length > 0
                                           ? setting.Name.Trim().ToUpper()[0].ToString()
                                           : "",
                                       setting.PatronymicName.Trim().Length > 0
                                           ? setting.PatronymicName.Trim().ToUpper()[0].ToString()
                                           : "");
            
        }
        return result;
    }

    private static string GetFolderPath(string rootFolder, int fid, int oid)
    {
        var resultPath = Path.Combine(rootFolder, string.Format("{0}_{1}", fid,oid));
        if (!Directory.Exists(resultPath))
            Directory.CreateDirectory(resultPath);
        return resultPath;
    }

    private static NotariusList GetNotariusList(NotarialServiceDataContext dc)
    {        
        var setting = dc.NotarialSettings.FirstOrDefault();
        if (setting == null) return null;

        return new NotariusList
                   {
                       IOisActive = setting.IOisActive,
                       Items = new List<Notarius>
                                   {
                                       new Notarius{Id = 1, Name = string.Format("{0} {1}. {2}.", setting.LastName, setting.Name,
                                                     setting.PatronymicName)},
                                       new Notarius{Id = 2, Name = string.Format("{0} {1}. {2}.", setting.LastNameIO, setting.NameIO,
                                                     setting.PatronymicNameIO)}
                                   }
                   };
               
    }


}

